<template>
  <el-dialog v-model="dialogVisible" :title="title" width="40%" destroy-on-close class="tag-select-dialog" @close="handleClose" :style="{ marginTop: '5vh' }">
    <div class="dialog-content">
      <!-- 搜索和筛选区域 -->
      <div class="filter-section">
        <div class="search-row">
          <el-input v-model="searchKeyword" placeholder="搜索标签名称" clearable class="search-input">
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>
          <div class="button-group">
            <el-button type="primary" @click="handleSearch">搜索</el-button>
            <el-button @click="handleReset">重置</el-button>
          </div>
        </div>
      </div>

      <!-- 标签卡片流式布局 -->
      <div class="tags-section" v-loading="loading">
        <div v-if="tagList.length === 0" class="empty-tip">暂无标签</div>
        <div class="tags-list">
          <template v-if="multiple">
            <el-tooltip :content="isAllSelected ? '取消全选' : '全选'" placement="top">
              <el-button class="select-all-inline-btn" circle size="small" @click="handleSelectAll" :type="isAllSelected ? 'success' : 'info'" plain>
                <el-icon v-if="!isAllSelected"><Check /></el-icon>
                <el-icon v-else><Close /></el-icon>
              </el-button>
            </el-tooltip>
          </template>
          <el-tag
            v-for="tag in tagList"
            :key="tag.id"
            :type="isSelected(tag) ? 'success' : 'info'"
            :effect="isSelected(tag) ? 'dark' : 'plain'"
            class="tag-item"
            :class="{ selected: isSelected(tag) }"
            @click="handleTagClick(tag)"
            style="cursor: pointer; margin: 8px 8px 0 0; font-size: 15px; padding: 8px 18px; border-radius: 20px"
          >
            {{ tag.label_name }}
          </el-tag>
        </div>
      </div>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'TagSelectDialog'
});
</script>

<script lang="ts" setup>
import { ref, computed, watch, onMounted } from 'vue';
import { Search, Check, Close } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { getAllLabel } from '@/api/userRate/label';

interface Tag {
  id: string;
  label_name: string;
}

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  multiple: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: '选择标签'
  },
  selectedTags: {
    type: Array as () => string[],
    default: () => []
  }
});

const emit = defineEmits(['update:modelValue', 'confirm', 'cancel']);

// 状态变量
const loading = ref(false);
const searchKeyword = ref('');
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0);
const tagList = ref<Tag[]>([]);
const tempSelectedTags = ref<Tag[]>([]);

// 计算属性
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
});

const isAllSelected = computed(() => {
  if (!props.multiple) return false;
  if (tagList.value.length === 0) return false;
  return tagList.value.every((tag) => tempSelectedTags.value.some((t) => t.id === tag.id));
});

// 方法
const fetchTags = async () => {
  loading.value = true;
  try {
    const res = await getAllLabel(searchKeyword.value || undefined);
    if (res.data) {
      // 由于API不支持分页，我们需要在前端进行分页处理
      const allTags = res.data.map((item: any) => ({
        id: item.id.toString(),
        label_name: item.label_name
      }));

      // 前端分页处理
      const startIndex = (currentPage.value - 1) * pageSize.value;
      const endIndex = startIndex + pageSize.value;
      tagList.value = allTags.slice(startIndex, endIndex);
      total.value = allTags.length;

      // 初始化临时选中数据
      if (props.selectedTags.length > 0) {
        tempSelectedTags.value = allTags.filter((tag: Tag) => props.selectedTags.includes(tag.id));
      }
    }
  } catch (error) {
    ElMessage.error('获取标签列表失败');
  } finally {
    loading.value = false;
  }
};

const handleReset = () => {
  searchKeyword.value = '';
  currentPage.value = 1;
  pageSize.value = 10;
  fetchTags();
};

const handleSearch = () => {
  currentPage.value = 1;
  fetchTags();
};

const handleSizeChange = (val: number) => {
  pageSize.value = val;
  currentPage.value = 1;
  fetchTags();
};

const handleCurrentChange = (val: number) => {
  currentPage.value = val;
  fetchTags();
};

const isSelected = (tag: Tag) => {
  return tempSelectedTags.value.some((t) => t.id === tag.id);
};

const handleCancel = () => {
  emit('cancel');
  dialogVisible.value = false;
};

const handleConfirm = () => {
  const selectedTags = tempSelectedTags.value.map((tag) => ({
    id: tag.id,
    label_name: tag.label_name
  }));
  emit('confirm', selectedTags);
  dialogVisible.value = false;
};

const handleClose = () => {
  searchKeyword.value = '';
  currentPage.value = 1;
};

// 卡片点击选中/取消逻辑
const handleTagClick = (tag: Tag) => {
  if (props.multiple) {
    if (isSelected(tag)) {
      tempSelectedTags.value = tempSelectedTags.value.filter((t) => t.id !== tag.id);
    } else {
      tempSelectedTags.value = [...tempSelectedTags.value, tag];
    }
  } else {
    tempSelectedTags.value = [tag];
  }
};

const handleSelectAll = () => {
  if (!props.multiple) return;
  if (isAllSelected.value) {
    // 取消全选本页
    tempSelectedTags.value = tempSelectedTags.value.filter((t) => !tagList.value.some((tag) => tag.id === t.id));
  } else {
    // 全选本页
    const ids = tempSelectedTags.value.map((t) => t.id);
    const newTags = tagList.value.filter((tag) => !ids.includes(tag.id));
    tempSelectedTags.value = [...tempSelectedTags.value, ...newTags];
  }
};

onMounted(() => {
  fetchTags();
});

// 监听弹窗显示状态
watch(
  () => props.modelValue,
  (val) => {
    if (val) {
      fetchTags();
    }
  }
);
</script>

<style lang="scss" scoped>
.tag-select-dialog {
  :deep(.el-dialog) {
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
    .el-dialog__header {
      margin: 0;
      padding: 20px 24px;
      border-bottom: 1px solid #f0f0f0;

      .el-dialog__title {
        font-size: 18px;
        font-weight: 600;
        color: #1f2937;
      }
    }

    .el-dialog__body {
      padding: 24px;
    }

    .el-dialog__footer {
      padding: 16px 24px;
      border-top: 1px solid #f0f0f0;
    }
  }
}

.dialog-content {
  .filter-section {
    margin-bottom: 20px;
    background: #f9fafb;
    padding: 16px;
    border-radius: 8px;

    .search-row {
      display: flex;
      gap: 12px;
      align-items: center;

      .search-input {
        flex: 1;
        min-width: 0;

        :deep(.el-input__wrapper) {
          box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
          background: #fff;

          &:hover,
          &:focus-within {
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
          }
        }
      }

      .button-group {
        display: flex;
        flex-shrink: 0;
      }
    }
  }

  .tags-section {
    position: relative;
    background: #fff;
    min-height: 120px;
    border-radius: 8px;
    padding: 24px 12px 8px 12px;
    margin-bottom: 8px;
    .empty-tip {
      color: #b0b0b0;
      text-align: center;
      padding: 32px 0;
    }
    .tags-list {
      display: flex;
      flex-wrap: wrap;
      gap: 16px 16px;
      justify-content: flex-start;
      align-items: flex-start;
      min-height: 48px;
      padding: 0 8px;
    }
    .select-all-inline-btn {
      margin: 8px 16px 0 0;
      background: #e0edff;
      border-radius: 50%;
      box-shadow: 0 4px 16px #3b82f644;
      border: 2px solid #3b82f6;
      transition: box-shadow 0.18s, transform 0.18s, background 0.18s;
      .el-icon {
        font-size: 22px;
        color: #2563eb;
        transition: color 0.18s;
      }
      &:hover {
        background: #3b82f6;
        box-shadow: 0 8px 24px #2563eb55;
        transform: scale(1.12);
        .el-icon {
          color: #fff;
        }
      }
      &.el-button--success {
        background: #3b82f6;
        border-color: #2563eb;
        .el-icon {
          color: #fff;
        }
      }
    }
    .tag-item {
      min-width: 100px;
      max-width: 180px;
      height: 38px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 20px;
      font-size: 15px;
      padding: 0 18px;
      margin: 0;
      background: #f6f8fa;
      color: #333;
      border: 1.5px solid transparent;
      box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
      cursor: pointer;
      transition: all 0.18s cubic-bezier(0.4, 0, 0.2, 1);
      user-select: none;
    }
    .tag-item.selected {
      border: 1.5px solid #3b82f6;
      color: #2563eb !important;
      background: #e0edff !important;
      font-weight: 600;
      box-shadow: 0 2px 8px #3b82f633;
    }
    .tag-item:hover {
      border: 1.5px solid #60a5fa;
      background: #f0f7ff;
      color: #2563eb;
      box-shadow: 0 2px 8px #60a5fa33;
    }
  }

  .pagination-container {
    padding: 16px 0 0 0;
    display: flex;
    justify-content: flex-end;
    background: transparent;
  }
}

:deep(.dialog-footer) {
  .el-button {
    padding: 8px 20px;
    font-weight: 500;
    border-radius: 6px;

    &--default {
      border-color: #e5e7eb;
      color: #4b5563;

      &:hover {
        border-color: #3b82f6;
        color: #3b82f6;
      }
    }

    &--primary {
      background: #3b82f6;
      border-color: #3b82f6;

      &:hover {
        background: #2563eb;
        border-color: #2563eb;
      }
    }
  }
}
</style> 